package com.hll.api.controller.xinhua;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hll.api.config.web.RespMessage;
import com.hll.api.entity.User;
import com.hll.api.enums.SMS;
import com.hll.api.exception.MyException;
import com.hll.api.service.UserService;
import com.hll.api.service.XinhuaService;
import com.hll.api.util.ValidateCodeUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.ui.context.Theme;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 登录注册操作
 * @author 何龙
 * @create 2019-07-13 16:45
 */
@RestController
@RequestMapping("/api/xinhua")
@Slf4j
public class XinhuaLoginController {
	/** 验证码 */
	private static final String VERIFICATION="verification";
	//注册验证码
	private static final String MOBILE_VERIFICATION="mobileverification";
	//登录验证码
	private static final String LOGIN_VERIFICATION="loginVerification";
	//修改验证码
	private static final String UPDATE_VERIFICATION="updateVerification";
	//注销验证码
	private static final String DELETE_VERIFICATION="deleteVerification";
	private static HashMap<String, Date> map = new HashMap<>();
	private static final Long TIMEOUT = 1000*50L;

	@Resource
	XinhuaService service;
	@Resource
	UserService userService;

	

	/** 注销账号 */
	@DeleteMapping("/user")
	public RespMessage userDelete(String code,HttpServletRequest request){
		if (StringUtils.isEmpty(code)){
			return RespMessage.error("验证码不能为空");
		}
		HttpSession session = request.getSession();
		User xinhuaUser = userService.getXinhuaUser(request);
		if (!code.equals(session.getAttribute(DELETE_VERIFICATION))){
			return RespMessage.error("验证码错误");
		}
		userService.removeById(xinhuaUser.getId());
		session.removeAttribute(User.USER_SESSION);
		session.removeAttribute(DELETE_VERIFICATION);
		return RespMessage.success("账户注销成功");
	}


	@PostMapping("/verification/delete")
	public RespMessage verificationDelete(HttpServletRequest request) throws Exception {
		HttpSession session = request.getSession();
		User xinhuaUser = userService.getXinhuaUser(request);
		String mobile = xinhuaUser.getMobile();
		if (isMobile(mobile)){
			RespMessage endsms = service.endsms(SMS.THECANCELLATION, mobile);
			if (endsms.getStatus()==0){
				Object datas = endsms.getDatas();
				log.debug("【{}】注销验证码为：{}",mobile,datas);
				session.setAttribute(DELETE_VERIFICATION,datas);
				map.put(mobile,new Date());
				return RespMessage.success("发送成功");
			}else {
				return endsms;
			}
		}
		return RespMessage.error("发送失败");
	}


	@PutMapping("/user/update/information")
	public RespMessage updateInformation(HttpServletRequest request, String name, String gender,
	                                     String year, String month, String day, String city,
	                                     String province, String county, String address){
		User user = userService.getXinhuaUser(request);
		if (!StringUtils.isEmpty(gender)&&!"男".equals(gender)&&!"女".equals(gender)){
			return RespMessage.error("性别只能为男、女");
		}
		user.setName(name);
		user.setAddress(address);
		user.setCity(city);
		user.setCounty(county);
		user.setDay(day);
		user.setGender(gender);
		user.setMonth(month);
		user.setProvince(province);
		user.setYear(year);
		userService.updateById(user);
		return RespMessage.success("修改成功");
	}



	/** 修改密码*/
	@PutMapping("/user/updatepass")
	public RespMessage userUpdatepass(String code,String pass,HttpServletRequest request){
		User user = userService.getXinhuaUser(request);
		HttpSession session = request.getSession();
		if (code==null){
			return RespMessage.error("验证码不能为空");
		}
		if (StringUtils.isEmpty(pass)){
			return RespMessage.error("密码不能为空");
		}
		if (!code.equals(session.getAttribute(UPDATE_VERIFICATION))){
			return RespMessage.error("手机验证码不正确");
		}
		user.setPass(pass);
		boolean b = userService.updateById(user);
		session.removeAttribute(UPDATE_VERIFICATION);
		return RespMessage.success("修改成功");
	}

	/** 修改密码时发送的验证码*/
	@PostMapping("/verification/update")
	public RespMessage verificationUpdate(HttpServletRequest request) throws Exception {
		HttpSession session = request.getSession();
		User xinhuaUser = userService.getXinhuaUser(request);
		String mobile = xinhuaUser.getMobile();
		if (isMobile(mobile)){
			RespMessage endsms = service.endsms(SMS.CHANGE_PASSWORD, mobile);
			if (endsms.getStatus()==0){
				Object datas = endsms.getDatas();
				log.debug("【{}】修改密码验证码为：{}",mobile,datas);
				session.setAttribute(UPDATE_VERIFICATION,datas);
				map.put(mobile,new Date());
				return RespMessage.success("发送成功");
			}else {
				return endsms;
			}
		}
		return RespMessage.error("发送失败");
	}


	/** 短信验证码登录 */
	@PostMapping("/login/mobile")
	public RespMessage loginMobile(String code,String mobile,HttpSession session) throws Exception {
		if (StringUtils.isEmpty(code)){
			return RespMessage.error("验证码不能为空");
		}else if (StringUtils.isEmpty(mobile)){
			return RespMessage.error("手机号不能为空");
		}else if (!code.equals(session.getAttribute(LOGIN_VERIFICATION))){
			return RespMessage.error("手机验证码有误");
		}
		User user = userService.getMobile(mobile);
		if (user==null){
			user=new User();
			user.setMobile(mobile);
			user.setPass(mobile);
			user.setImg("https://ws1.sinaimg.cn/large/005S8gRNly1g4yd4ewb85j3040040a9x.jpg");
			userService.save(user);
			service.endsms(SMS.SUCCESS,mobile);
		}
		session.setAttribute(User.USER_SESSION,user.getId());
		return RespMessage.success("登陆成功");
	}

	/** 登录短信验证码发送 */
	@PostMapping("/verification/login")
	public RespMessage verificationLogin(String code,String mobile,HttpSession session) throws Exception {
		if (StringUtils.isEmpty(code)){
			return RespMessage.error("图片验证码不能为空");
		}
		if (!code.equals(session.getAttribute(VERIFICATION))){
			return RespMessage.error("图片验证码有误");
		}
		if (isMobile(mobile)){
			RespMessage endsms = service.endsms(SMS.THE_LOGIN, mobile);
			if (endsms.getStatus()==0){
				Object datas = endsms.getDatas();
				log.debug("【{}】登录验证码：{}",mobile,datas);
				session.setAttribute(LOGIN_VERIFICATION,datas);
				map.put(mobile,new Date());
				return RespMessage.success("发送成功");
			}else {
				return endsms;
			}
		}else {
			return RespMessage.error("手机号码格式不正确");
		}
	}


	/** 登录接口 */
	@PostMapping("/login/account")
	public RespMessage account(String mobile,String pass,HttpSession session){
		if (StringUtils.isEmpty(mobile)||StringUtils.isEmpty(pass)){
			return RespMessage.error("手机号和密码不能为空");
		}
		User mobile1 = userService.getMobile(mobile);
		if (mobile1==null){
			return RespMessage.error("用户不存在");
		}else if (!pass.equals(mobile1.getPass())){
			return RespMessage.error("密码有误");
		}
		session.setAttribute(User.USER_SESSION,mobile1.getId());
		return RespMessage.success("登陆成功");
	}

	/** 退出登录 */
	@GetMapping("/logout")
	public RespMessage logout(HttpSession session){
		session.removeAttribute(User.USER_SESSION);
		return RespMessage.success("退出成功");
	}

	/** 获取当前登录用户 */
	@GetMapping("/user")
	public RespMessage getUser(HttpServletRequest request){
		User user = userService.getXinhuaUser(request);
		user.setPass(null);
		return RespMessage.success(user,null);
	}

	/** 删除账号 */
	@GetMapping("/user/delete/{mobile}")
	public RespMessage deleteUer(@PathVariable String mobile){
		QueryWrapper<User> wrapper = new QueryWrapper<>();
		wrapper.eq("mobile",mobile);
		boolean remove = userService.remove(wrapper);
		return RespMessage.success("账号删除成功");
	}

	/** 注册 */
	@PostMapping("/registered")
	public RespMessage registered(String mobile,String pass,String mobileCode,HttpSession session){
		if (StringUtils.isEmpty(mobileCode)){
			return RespMessage.error("验证码不能为空");
		}
		if (StringUtils.isEmpty(mobile)||StringUtils.isEmpty(pass)){
			return RespMessage.error("手机号和密码不能为空");
		}
		if (isMobile(mobile)){
			Object attribute = session.getAttribute(MOBILE_VERIFICATION);
			if (attribute==null||!attribute.equals(mobileCode)){
				return RespMessage.error("手机验证码有误");
			}
			if (userService.getMobile(mobile)!=null){
				return RespMessage.error("该手机号已经被注册");
			}
			User user = new User();
			user.setMobile(mobile);
			user.setPass(pass);
			user.setImg("https://ws1.sinaimg.cn/large/005S8gRNly1g4yd4ewb85j3040040a9x.jpg");
			boolean save = userService.save(user);
			if (save){
				session.removeAttribute(VERIFICATION);
				session.removeAttribute(MOBILE_VERIFICATION);
				return RespMessage.success("注册成功");
			}else {
				return RespMessage.error("注册失败");
			}
		}else {
			return RespMessage.error("手机号格式不正确");
		}

	}


	@PostMapping("/registered/code")
	public RespMessage registeredCode(String verificationCode,String mobile,HttpSession session) throws Exception {
		if (StringUtils.isEmpty(verificationCode)){
			return RespMessage.error("验证码不能为空");
		}
		Object attribute = session.getAttribute(VERIFICATION);
		if (attribute==null|| !attribute.equals(verificationCode)){
			return RespMessage.error("验证码错误");
		}
		isSend(mobile);
		if (isMobile(mobile)){
			RespMessage message = service.endsms(SMS.REGISTERED, mobile);
			if (message.getStatus()==0){
				map.put(mobile,new Date());
				Object datas = message.getDatas();
				log.debug("【{}】注册验证码为：{}",mobile,datas);
				session.setAttribute(MOBILE_VERIFICATION,datas);
				return RespMessage.success("发送成功");
			}else {
				return message;
			}
		}else {
			return RespMessage.error("手机号码格式有误");
		}
	}



	/** 获取验证码图片 */
	@GetMapping("/verification/code")
	public RespMessage verificationCode(HttpSession session){
		ValidateCodeUtil.Validate randomCode = ValidateCodeUtil.getRandomCode();
		String value = randomCode.getValue();
		log.debug("图片验证码：{}",value);
		session.setAttribute(VERIFICATION,value);
		JSONObject object = new JSONObject();
		object.put("base64Str","data:image/png;base64,"+randomCode.getBase64Str());
		return RespMessage.success(object,null);
	}


	/** 清除 */
	private void isSend(String phone) throws MyException{
		if (isMobile(phone)){
			Date date = map.get(phone);
			if (date!=null){
				long l = System.currentTimeMillis() - date.getTime();
				if (l>TIMEOUT){
					throw new MyException("40秒以内只能发送一次验证码");
				}
			}
		}
		cleanUpThe();
	}

	private void cleanUpThe(){
		for (Map.Entry<String, Date> entry : map.entrySet()) {
			if (System.currentTimeMillis()-entry.getValue().getTime()>1000*60*60){
				map.remove(entry.getKey());
			}
		}
	}




	private static final String REGEX;

	static {
		REGEX = "^((13[0-9])|(14[5,7,9])|(15([0-3]|[5-9]))|(166)|(17[0,1,3,5,6,7,8])|(18[0-9])|(19[8|9]))\\d{8}$";
	}

	/** 验证是否为手机号码 */
	private boolean isMobile(String phone){
		if (StringUtils.isNotEmpty(phone)){
			if (phone.length() != 11) {
				return false;
			} else {
				Pattern p = Pattern.compile(REGEX);
				Matcher m = p.matcher(phone);
				return m.matches();
			}
		}
		return false;
	}


}
